<!--
 * @Author: daidai
 * @Date: 2022-03-01 11:17:39
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2022-09-29 15:50:18
 * @FilePath: \web-pc\src\pages\big-screen\view\indexs\center-map.vue
-->
<template>
  <!-- 这是Vue组件的模板部分，用于定义组件的HTML结构 -->
  <div class="centermap">
    <!-- 以下div用于包裹地图标题相关内容，起到组织和布局的作用 -->
    <div class="maptitle">
      <!-- 这个空的div可能用于在标题左边添加一些空白或特定样式的占位空间，目前样式可能在别处定义 -->
      <div class="zuo"></div>
      <!-- 通过插值表达式绑定组件data中的maptitle数据，用于动态显示地图标题 -->
      <span class="titletext">{{ maptitle }}</span>
      <!-- 这个空的div可能用于在标题右边添加一些空白或特定样式的占位空间，目前样式可能在别处定义 -->
      <div class="you"></div>
    </div>
    <!-- 以下div用于包裹地图主体内容相关部分，包括地图展示区域和可能的交互元素等 -->
    <div class="mapwrap">
      <!-- 这里使用了一个名为dv-border-box-13的组件，可能是自定义的用于给地图内容添加特定边框样式的组件 -->
      <dv-border-box-13>
        <!-- 这个div用于显示"中国"字样，并且绑定了点击事件getData('china')，当code不等于'china'时显示。点击它可能会触发获取中国相关地图数据的操作 -->
        <div class="quanguo" @click="getData('china')" v-if="code!== 'china'">
          中国
        </div>

        <!-- 使用Echart组件来展示地图，传入id、配置选项options，并设置了ref属性以便在脚本部分能获取到该组件实例，进而进行更多操作，比如更新地图数据等 -->
        <Echart id="CenterMap" :options="options" ref="CenterMap" />
      </dv-border-box-13>
    </div>
  </div>
</template>

<script>
import xzqCode from "../../utils/map/xzqCode";
import { currentGET } from "api/modules";
import * as echarts from "echarts";
import { GETNOBASE } from "api";
import {myCurrentList} from "@/api/modules/centerMap";

// 定义一个名为center-map的Vue组件
export default {
  data() {
    return {
      // 地图标题的数据属性，初始值为"招商地图"，可在组件的不同生命周期或方法中根据需要修改该值，以实现动态改变地图标题的效果
      maptitle: "招商地图",
      // 用于存储ECharts地图的配置选项，初始为空对象，后续会在相关方法中根据获取到的数据等情况进行填充和更新，以定制地图的显示效果等
      options: {},
      // 用于标识当前展示的区域代码，初始值为'china'，代表中国，对于其他地市可能是对应的行政编码。通过改变这个值可以切换展示不同区域的地图数据
      code: "china",
      // 用于标识是否已经绑定了ECharts的点击事件，初始值为false，在成功绑定点击事件后会将该值设为true，这样可以避免重复绑定点击事件导致的异常情况
      echartBindClick: false,
      // 用于标识是否要展示南海群岛，修改此值需要刷新页面，初始值为false。可根据具体业务需求决定是否展示南海群岛相关内容在地图上
      isSouthChinaSea: false
    };
  },
  created() {
    // Vue组件的created生命周期钩子，在组件实例刚刚被创建时调用，此时DOM还未挂载，通常可在此处进行一些数据的初始化设置、异步请求的初始化等操作，这里暂时为空实现
    this.getData("china");
  },

  mounted() {
    // Vue组件的mounted生命周期钩子，在组件挂载到DOM节点后执行，此时可以进行与DOM相关的操作，比如获取DOM元素、初始化一些基于DOM的插件等
    // 这里打印xzqCode对象（可能是用于存储行政区编码相关信息的对象），方便调试查看其内部数据结构和内容，以便后续根据编码进行相关的地图数据处理等操作
    // console.log(xzqCode);
    // 调用getData函数并传入'china'作为参数，用于获取中国相关的数据并初始化地图展示，一般在组件挂载完成后会首先获取默认展示区域（这里是中国）的数据来进行地图的初始呈现

  },
  methods: {
    getData(code) {
      // getData函数用于根据传入的区域代码获取相关数据，并处理与地图展示相关的一系列操作，比如获取数据成功后进一步处理数据、更新地图等
      // 调用currentGET函数（从api/modules模块导入的用于获取数据的函数），传入参数"big8"和包含区域代码的对象，向后台接口请求对应区域的相关数据
      currentGET("big8", { regionCode: code }).then((res) => {
        // 打印获取到的设备分布相关数据，方便调试查看数据的具体内容、格式等信息，以便确认数据是否符合预期，有助于排查数据获取过程中可能出现的问题
        console.log("招商分布", res);
        if (res.success) {
          // 如果获取数据成功，调用getGeojson函数处理地理JSON数据，并传入区域代码和数据列表，以便对获取到的数据进行进一步处理，使其符合地图展示的要求
          this.getGeojson(res.data.regionCode, res.data.dataList);
          // 调用mapclick函数处理地图点击事件相关的逻辑，比如绑定点击事件、根据点击区域切换地图数据等操作
          // this.mapclick();
        } else {
          // 如果获取数据失败，使用$Message.warning方法（可能是组件库提供的显示警告信息的方法）显示失败提示信息，告知用户获取数据出现问题以及具体的错误消息内容
          this.$Message.warning(res.msg);
        }
      });
    },
    /**
     * @description: 获取geojson
     * @param {*} name china 表示中国 其他省份行政区编码
     * @param {*} mydata 接口返回列表数据
     * @return {*}
     */
    async getGeojson(name, mydata) {
      // getGeojson函数主要负责获取地理JSON数据并进行一系列相关处理，比如根据区域名称获取对应的地理JSON文件、注册地图到ECharts等操作
      // 将传入的区域代码赋值给组件的code数据属性，用于记录当前展示的区域，方便在组件的其他地方根据该值进行相关判断和操作，比如确定当前地图展示的是哪个区域的数据
      this.code = name;
      // 根据是否要展示南海群岛以及当前区域是否为中国，确定要获取的地理JSON数据的名称。如果要展示南海群岛且当前区域是中国，会使用特定的名称（如chinaNanhai）来获取对应的地理JSON数据
      let geoname = name;
      if (this.isSouthChinaSea && name == "china") {
        geoname = "chinaNanhai";
      }
      // 尝试获取已经注册过的地图数据，如果存在则直接使用。通过echarts.getMap(name)尝试获取已注册的地图数据，若获取到则进行下一步处理
      let mapjson = echarts.getMap(name);
      if (mapjson) {
        // 如果获取到已注册的地图数据，将其转换为geoJSON格式，以便后续在ECharts中正确使用。不同的地图数据格式可能在ECharts中的处理方式略有不同，统一转换为geoJSON格式更便于后续操作
        mapjson = mapjson.geoJSON;
      } else {
        // 如果未注册过该地图，通过GETNOBASE函数（从api模块导入的用于获取数据的函数）获取对应的地理JSON数据文件。这里使用await关键字表示这是一个异步操作，会等待该函数执行完成并返回结果后再继续执行后续代码
        mapjson = await GETNOBASE(`./map-geojson/${geoname}.json`).then((res) => {
          return res;
        });
        // 将获取到的地理JSON数据注册到ECharts中，以便后续能够正确识别并展示对应的地图区域。注册地图数据后，ECharts才能根据该注册信息展示相应的地图内容
        echarts.registerMap(name, mapjson);
      }
      // 用于存储每个省份的中心点坐标信息的对象，后续会根据地理JSON数据计算出每个省份的中心点坐标并存储在此对象中
      let cityCenter = {};
      // 获取地理JSON数据中的features数组，该数组可能包含各个省份的地理信息，比如省份的边界坐标、中心点坐标、名称等属性
      let arr = mapjson.features;
      // 遍历地理JSON数据中的每个省份信息，计算并存储其中心点坐标到cityCenter对象中。通过遍历features数组中的每个元素（代表一个省份的地理信息），获取其中心点坐标并存储到cityCenter对象中
      arr.map((item) => {
        cityCenter[item.properties.name] =
            item.properties.centroid || item.properties.center;
      });
      // 用于存储经过处理后的新数据数组，后续会将接口返回的数据与计算得到的省份中心点坐标等信息进行整合，生成新的数据格式并存储在此数组中
      let newData = [];
      // 遍历接口返回的数据列表mydata，对每个数据项进行处理，判断其对应的省份是否有中心点坐标记录，如果有则进行数据整合操作
      mydata.map((item) => {
        if (cityCenter[item.name]) {
          // 将省份名称、中心点坐标和对应的数据值组合成新的数据格式，并添加到newData数组中。这样整合后的新数据更便于在地图上进行展示和相关操作
          newData.push({
            name: item.name,
            value: cityCenter[item.name].concat(item.value)
          });
        }
      });
      // 调用init函数进行地图的初始化配置，并传入区域代码、原始数据和处理后的新数据，以便根据这些数据配置地图的各种显示效果、数据绑定等，使地图能够正确展示相关信息
      this.init(name, mydata, newData);
    },
    init(name, data, data2) {
      // init函数用于配置ECharts地图的各种参数，如地图的样式、数据系列、提示框设置等，以实现定制化的地图展示效果
      // 定义地图的顶部偏移量，初始值为45，用于控制地图在容器中的垂直位置，可根据实际布局需求调整该值，以达到合适的地图展示位置
      let top = 45;
      // 定义地图的缩放级别，初始值为1.05，用于控制地图的缩放程度，数值越大地图显示越详细，可根据需要调整该值以展示合适的地图细节
      let zoom = 1.05;
      // 配置ECharts地图的选项对象，通过设置该对象的各种属性来定制地图的各种显示效果，比如背景颜色、提示框样式、图例样式等





      let option = {
        // 设置地图的背景颜色为透明，使地图背景与页面背景融合或者根据页面其他元素的布局需求进行透明设置，以便达到更好的视觉效果
        backgroundColor: "rgba(0,0,0,0)",
        // 设置地图的提示框默认不显示，可根据需要在后续根据特定条件（如鼠标悬停在地图区域上）再设置提示框显示并定制其内容，以提供更详细的信息展示
        tooltip: {
          show: false
        },
        // 设置地图的图例默认不显示，图例通常用于展示地图数据系列的标识等信息，如果不需要展示图例可将其设置为不显示，以简化地图界面
        legend: {
          show: false
        },
        visualMap: {
          // 设置视觉映射组件的左边距为20，用于控制视觉映射组件在地图容器中的水平位置，可根据布局需求调整该值，以达到合适的组件布局位置
          left: 20,
          // 设置视觉映射组件的下边距为20，用于控制视觉映射组件在地图容器中的垂直位置，可根据布局需求调整该值，以达到合适的组件布局位置
          bottom: 20,
          // 定义视觉映射的分段规则，用于根据数据值范围设置不同的显示样式，比如根据数据的大小范围设置不同的颜色、透明度等视觉效果，以直观地展示数据差异
          pieces: [
            { gte: 1000000, label: "1000000元以上" }, // 不指定 max，表示 max 为无限大（Infinity）。这里表示数据值大于等于1000时对应的显示样式
            { gte: 500001, lte: 1000000, label: "500000元-1000000元" },
            { gte: 100001, lte: 500000, label: "100000-500000元" },
            { gte: 40001, lte: 100000, label: "40000元-100000元" },
            { gte: 10001, lte: 40000, label: "10000-40000元" },
            { lte: 10000, label: "10000元以下" } // 不指定 min，表示 min 为无限大（-Infinity）。这里表示数据值小于等于9时对应的显示样式
          ],
          inRange: {
            // 定义视觉映射组件在数据值范围内的渐变颜色设置，通过设置不同的颜色值数组来实现根据数据值大小渐变显示颜色的效果，以提供更直观的视觉反馈
            // 渐变颜色，从小到大
            color: [
              "#9806ed",
              "#6b0edc",
              "#382a71",
              "#202478",
              "#1d6786",
              "#1781b5"
            ]
          },
          textStyle: {
            // 设置视觉映射组件文本的颜色为白色，用于设置视觉映射组件中显示的文本（如分段标签等）的颜色，以确保文本在相应背景下清晰可见
            color: "#fff"
          }
        },
        geo: {
          // 设置地图的名称，与传入的区域代码对应，确保ECharts能正确识别并展示对应的地图区域，避免出现地图显示错误的情况
          map: name,
          // 设置地图不可漫游，即不能通过鼠标拖动等操作移动地图范围，可根据需求设置为可漫游或不可漫游，这里设置为不可漫游可能是出于特定业务需求或布局考虑
          roam: false,
          // 设置是否允许选中多个区域，这里设置为不允许，可根据业务需求决定是否允许用户在地图上选中多个区域进行相关操作，比如进行数据对比等
          selectedMode: false,
          // 设置地图的缩放级别，与前面定义的zoom变量对应，用于控制地图的缩放程度，确保地图在不同区域切换或缩放操作时保持一致的缩放效果
          zoom: zoom,
          // 设置地图的顶部偏移量，与前面定义的top变量对应，用于控制地图在容器中的垂直位置，确保地图在不同布局调整时能准确显示在合适的位置
          top: top,
          // aspectScale: 0.78,  // 可能是用于控制地图宽高比的设置，这里暂时注释掉未使用，可能在后续根据具体需求再启用
          // 设置地图默认不显示，可能后续根据其他条件（如数据加载完成、用户操作等）再显示，可根据业务流程设置地图的显示时机，以达到更好的用户体验
          show: false
        },
        series: [
          {
            name: "MAP",
            type: "map",
            map: name,
            // aspectScale: 0.78,  // 可能是用于控制地图宽高比的设置，这里暂时注释掉未使用，可能在后续根据具体需求再启用
            // 设置地图数据系列的数据，这里传入的是原始数据data，该数据可能是从接口获取并经过一定处理后的与地图区域对应的原始数据，用于在地图上展示相关信息
            data: data,
            // data: [1,100],  // 这里可能是示例数据或者之前调试时遗留的注释掉的数据，实际使用中传入的是处理后的原始数据，用于准确展示地图相关数据
            // 设置是否允许选中多个区域，这里设置为不允许，与前面geo设置中的selectedMode保持一致，可根据业务需求决定是否允许选中多个区域，以确保操作的一致性
            selectedMode: false,
            // 设置地图数据系列的缩放级别，与前面定义的zoom变量对应，用于控制地图数据系列的缩放程度，确保数据系列在地图缩放操作时能正确显示
            zoom: zoom,
            geoIndex: 1,
            top: top,
            tooltip: {
              show: true,
              formatter: function (params) {
                if (params.data) {
                  // 如果当前鼠标悬停或点击的地图区域有对应的数据，返回区域名称和对应的数据值拼接后的字符串，用于在提示框中显示详细信息，以便用户了解该区域的具体数据情况
                  return params.name + "：" + params.data["value"];
                } else {
                  // 如果当前区域没有对应的数据，只返回区域名称，在提示框中显示基本的区域信息，让用户知道当前鼠标所在的区域
                  return params.name;
                }
              },
              backgroundColor: "rgba(0,0,0,.6)",
              borderColor: "rgba(147, 235, 248,.8)",
              textStyle: {
                color: "#FFF",
              },
            },
            label: {
              show: true,
              color: "#ffffff",
              // position: [-10, 0],
              formatter: function (val) {
                // console.log('val',val)
                if (val.data !== undefined) {
                  return val.name.substring(0, 2);
                } else {
                  return val.name.substring(0, 2);
                }
              },
              rich: {},
            },
            emphasis: {
              label: {
                show: false,
              },
              itemStyle: {
                areaColor: "#389BB7",
                borderWidth: 1,
              },
            },
            itemStyle: {
              borderColor: "rgba(147, 235, 248, .8)",
              borderWidth: 1,
              areaColor: {
                type: "radial",
                x: 0.5,
                y: 0.5,
                r: 0.8,
                colorStops: [
                  {
                    offset: 0,
                    color: "rgba(147, 235, 248, 0)", // 0% 处的颜色
                  },
                  {
                    offset: 1,
                    color: "rgba(147, 235, 248, .2)", // 100% 处的颜色
                  },
                ],
                globalCoord: false, // 缺为 false
              },
              shadowColor: "rgba(128, 217, 248, .3)",
              shadowOffsetX: -2,
              shadowOffsetY: 2,
              shadowBlur: 10,
            },
          },
          {
            data: data2,
            type: "effectScatter",
            coordinateSystem: "geo",
            symbolSize: function (val) {
              return 4;
              // return val[2] / 50;
            },
            legendHoverLink: true,
            showEffectOn: "render",
            rippleEffect: {
              // period: 4,
              scale: 6,
              color: "rgba(255,255,255, 1)",
              brushType: "fill",
            },
            tooltip: {
              show: true,
              formatter: function (params) {
                if (params.data) {
                  return params.name + "：" + params.data["value"][2];
                } else {
                  return params.name;
                }
              },
              backgroundColor: "rgba(0,0,0,.6)",
              borderColor: "rgba(147, 235, 248, .8)",
              textStyle: {
                color: "#FFF",
              },
            },
            label: {
              formatter: (param) => {
                return param.name.slice(0, 2);
              },

              fontSize: 11,
              offset: [0, 2],
              position: "bottom",
              textBorderColor: "#fff",
              textShadowColor: "#000",
              textShadowBlur: 10,
              textBorderWidth: 0,
              color: "#FFF",
              show: true,
            },
            // colorBy: "data",
            itemStyle: {
              color: "rgba(255,255,255,1)",
              borderColor: "rgba(2255,255,255,2)",
              borderWidth: 4,
              shadowColor: "#000",
              shadowBlur: 10,
            },
          },
        ],
         //动画效果
            animationDuration: 1000,
            animationEasing: 'linear',
            animationDurationUpdate: 1000
      };
      console.log('_option', option);
      // todo 请求接口
      window.setInterval(() => {
        myCurrentList().then((res) => {
          console.log('===>>>', res);
          // option.series[1].data = [];
          option.series[0].data = res.data;
          this.options = option;
        });
      }, 3000);

    },
    message(text) {
      this.$Message({
        text: text,
        type: "warning",
      });
    },
    mapclick() {
      if (this.echartBindClick) return;
      //单击切换到级地图，当mapCode有值,说明可以切换到下级地图
      this.$refs.CenterMap.chart.on("click", (params) => {
        // console.log(params);
        let xzqData = xzqCode[params.name];
        if (xzqData) {
          this.getData(xzqData.adcode);
        } else {
          this.message("暂无下级地市!");
        }
      });
      this.echartBindClick = true;
    },
  },
};
</script>
<style lang="scss" scoped>
.centermap {
  margin-bottom: 30px;

  .maptitle {
    height: 60px;
    display: flex;
    justify-content: center;
    padding-top: 10px;
    box-sizing: border-box;

    .titletext {
      font-size: 28px;
      font-weight: 900;
      letter-spacing: 6px;
      background: linear-gradient(
        92deg,
        #0072ff 0%,
        #00eaff 48.8525390625%,
        #01aaff 100%
      );
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      margin: 0 10px;
    }

    .zuo,
    .you {
      background-size: 100% 100%;
      width: 29px;
      height: 20px;
      margin-top: 8px;
    }

    .zuo {
      background: url("../../assets/img/xiezuo.png") no-repeat;
    }

    .you {
      background: url("../../assets/img/xieyou.png") no-repeat;
    }
  }

  .mapwrap {
    height: 548px;
    width: 100%;
    // padding: 0 0 10px 0;
    box-sizing: border-box;
    position: relative;

    .quanguo {
      position: absolute;
      right: 20px;
      top: -46px;
      width: 80px;
      height: 28px;
      border: 1px solid #00eded;
      border-radius: 10px;
      color: #00f7f6;
      text-align: center;
      line-height: 26px;
      letter-spacing: 6px;
      cursor: pointer;
      box-shadow: 0 2px 4px rgba(0, 237, 237, 0.5),
        0 0 6px rgba(0, 237, 237, 0.4);
    }
  }
}
</style>
